package com.xiaobaibai.service.impl;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.xiaobaibai.common.UserCommon;
import com.xiaobaibai.entity.UserAdmin;
import com.xiaobaibai.service.ITokenService;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Service
public class TokenServiceImpl implements ITokenService{

    @Value("${TokenAssert}")
    private String TokenAssert;

    private static String TOKEN;

    @Override
    public String getToken(Integer userId) {
        Date date = new Date();
        String token = JWT.create()
                //下面这
//                .withAudience(userId.toString())//发给谁的签名
                .withClaim(UserCommon.authenticationUserId,userId)
//                .withClaim(TokenCommon.TokenName,userAdmin.getUsername())
//                .withClaim("还可以自定义key","还可以自定义value")
//                .withIssuer("xiaobaibai")//谁发放的签名
//                .withSubject("subject")//签名的主题
//                .withNotBefore(date)//签名的生效时间
                .withIssuedAt(date)//签名的生成时间
                .withExpiresAt(DateUtils.addHours(date, 1))//签名失效时间
//                .withJWTId(UUID.randomUUID().toString())//jwt的编号,相当于一个jwt的id
                .sign(Algorithm.HMAC256(TokenAssert));//到时解密用的密匙(只能服务器知道)
        return token;
    }

    @Override
    public Map<String,Object> checkToken(String token) {

        JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(TokenAssert)).build();

        Integer userId=null;
        DecodedJWT decodedJWT=null;
        try {
            decodedJWT = jwtVerifier.verify(token);
            userId=decodedJWT.getClaim(UserCommon.authenticationUserId).asInt();
        }catch (Exception e){
            return null;
        }

        Map<String,Object> map=new HashMap<>();
        map.put("userId",userId);
        map.put("decodedJWT",decodedJWT);
        return map;
    }

    @Override
    public String refreshToken(Authentication authentication) {

        DecodedJWT decodedJWT = (DecodedJWT) authentication.getCredentials();

        Date expiresAt = decodedJWT.getExpiresAt();//获取失效时间

        //假如还有三十分钟就过期了,就刷新一下
        Date date = DateUtils.addMinutes(new Date(), 30);

        if(expiresAt.before(date)){//失效时间在(现在时间后的一个小时)之前

            Integer userId = decodedJWT.getClaim(UserCommon.authenticationUserId).asInt();

            return getToken(userId);
        }
        return null;
    }

}
